package com.fei.source;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import http.HttpClientUtil;
import util.XMLDoc;

public class GetSource {
	private final static String BASE_PACKAGE = "D:\\downLoadSource";
	private final static String BASE_URL = "http://source.jd.com";

	private final static int FILE_TYPE_FILE = 1;
	private final static int FILE_TYPE_DIR = 2;
	private final static String DEFAULT_BRANCH = "master";

	public static void main(String[] args) {

//		String projectName = "configCenter-zookeeper-common";
//		String projectName = "httpClientCommon";
//		String projectName = "userTracer";
		String projectName = "configTracer";
		String branch = "业务开放平台";
		new GetSource().start(projectName,branch);
	}

	private void start(String projectName,String branch) {
		if(StringUtils.isEmpty(branch)){
			branch = DEFAULT_BRANCH;
		}

		String url = "http://source.jd.com/app/" + projectName;

		String projectPath = BASE_PACKAGE + File.separator + projectName;

		File file = new File(projectPath);
		if (!file.exists()) {
			file.mkdirs();
		}

		downLoadSource(projectPath, url,branch);
	}

	private void downLoadSource(String filePath, String url,String branch) {
		String result = doRequest(url,branch);

		List<String> urlList = parseFirstLevelData(result, filePath,branch);

		dfsDownLoad(urlList, filePath,branch);
	}

	private void dfsDownLoad(List<String> urlList, String currentFilePath,String branch) {
		for (String url : urlList) {
			dfsDownLoad(url, currentFilePath,branch);
		}
	}

	private void dfsDownLoad(String url, String currentFilePath,String branch) {
		String fullUrl = BASE_URL + url;

		if (url.contains(".")) {

			String fileName = url.substring(url.lastIndexOf("/") + 1, url.length());
			
			File file = new File(currentFilePath + File.separator + fileName);
			try {
				if (!file.exists()) {
					file.createNewFile();
				}

				this.writeToFile(getXmlData(doRequest(fullUrl,branch)), file);

			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {

			String directorName = url.substring(url.lastIndexOf("/") + 1, url.length());

			File file = new File(currentFilePath + File.separator + directorName);
			if (!file.exists()) {
				file.mkdirs();
			}

			XMLDoc xmlDoc = this.getXmlData(this.doRequest(fullUrl,branch));

			NodeList nodeList = XMLDoc.selectNodes("div/table/tr", xmlDoc.getRootElement());
			List<String> urlList = new ArrayList<>();
			for (int i = 0; i < nodeList.getLength(); i++) {
				Node node = nodeList.item(i);

				if (!(node instanceof Element))
					continue;

				Element element = (Element) node;

				Node aNode = XMLDoc.selectSingleNode("td/a", element);

				String nodeContent = aNode.getTextContent().trim();
				
				// 返回上一层级的两点
				if(nodeContent.contains("..")) continue;
				
				Element el = (Element)aNode;
				String nextLevelUrl = el.getAttribute("href").trim();
				
				urlList.add(nextLevelUrl);
			}

			this.dfsDownLoad(urlList, file.getAbsolutePath(),branch);
		}
	}

	private List<String> parseFirstLevelData(String result, String filePath,String branch) {
		XMLDoc xmlDoc = getXmlData(result);

		NodeList nodeList = XMLDoc.selectNodes("div/li/div/a", xmlDoc.getRootElement());

		List<String> urlList = new ArrayList<>();

		for (int i = 0; i < nodeList.getLength(); i++) {
			Node node = nodeList.item(i);

			if (!(node instanceof Element))
				continue;

			Element element = (Element) node;

			String url = element.getAttribute("href");

			if (url.contains(".")) {

				String fileName = element.getTextContent().trim();
				if(fileName.contains(".log")) continue;
				
				File file = new File(filePath + File.separator + fileName);
				try {
					if (!file.exists()) {
						file.createNewFile();
					}

					String httpUrl = BASE_URL + url;
					writeToFile(getXmlData(doRequest(httpUrl,branch)), file);

				} catch (IOException e) {
					e.printStackTrace();
				}
			} else {
				String directorName = element.getTextContent().trim();

				File file = new File(filePath + File.separator + directorName);
				if (!file.exists()) {
					file.mkdirs();
				}

				urlList.add(url);
			}
		}

		return urlList;
	}

	private void writeToFile(XMLDoc xmlDoc, File file) {
		Node n = XMLDoc.selectSingleNode("div/table/tr/td/div/div", xmlDoc.getRootElement());

		if(n == null) {
			try {
				System.out.println("无法获取节点,File:" + file.getName() + ",xmlDoc:" + xmlDoc.asXML());
			} catch (IOException e) {
				e.printStackTrace();
			}
			return;
		}
		
		String code = n.getTextContent();

		try {
			FileUtils.write(file, code);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private XMLDoc getXmlData(String result) {
		if (result.indexOf("tab-content") < 0) {
			System.out.println("没有tab-content,result:" + result);
			return null;
		}

		result = result.substring(result.indexOf("tab-content") - 12, result.lastIndexOf("tab-content") - 10)
				.replace("<ul>", "");
		
		result = result.replace("&mdash", "")
				.replace("&otilde", "")
				.replace("&middot", "")
				.replace("&thorn", "")
				.replace("&Icirc", "")
				.replace("&ntilde", "")
				.replace("&AElig", "")
				.replace("&divide","")
				.replace("&para","")
				.replace("&Euml","")
				.replace("&iquest","")
				.replace("&Uacute","")
				.replace("&uacute","")
				.replace("&cent","")
				.replace("&Iacute","")
				.replace("&Ecirc", "")
				.replace("&yacute", "")
				.replace("&Yacute", "")
				.replace("&frac34", "")
				.replace("&Aacute", "")
				.replace("&aacute", "")
				.replace("&Auml", "")
				.replace("&not", "")
				.replace("&Ugrave", "")
				.replace("&Ograve", "")
				.replace("&ograve", "")
				.replace("&raquo", "")
				.replace("&frac12", "")
				.replace("&micro", "")
				.replace("&atilde", "")
				.replace("&Atilde", "")
				.replace("&acute", "")
				.replace("&Oacute", "")
				.replace("&ucirc", "")
				.replace("&plusmn", "")
				.replace("&oacute", "")
				.replace("&ordm", "")
				.replace("&brvbar", "")
				.replace("&sup1", "")
				.replace("&pound", "")
				.replace("&sup2", "")
				.replace("&Agrave", "")
				.replace("&cedil", "")
				.replace("&times", "")
				.replace("&eacute", "")
				.replace("&Eacute", "")
				.replace("&sup3", "")
				.replace("&Oslash", "")
				.replace("&oslash", "")
				.replace("&auml", "")
				.replace("&iacute", "")
				.replace("&Aring", "")
				.replace("&Ouml", "")
				.replace("&ouml", "")
				.replace("&Ocirc", "")
				.replace("&igrave", "")
				.replace("&egrave", "")
				.replace("&Ccedil", "")
				.replace("&frac14", "")
				.replace("&ETH", "")
				.replace("&ordf", "")
				.replace("&Iuml", "")
				.replace("&acirc", "")
				.replace("&uml", "")
				.replace("&Uuml", "")
				.replace("&ocirc", "")
				.replace("&deg", "")
				.replace("&yen", "")
				.replace("&sect", "")
				.replace("&Egrave", "")
				.replace("&laquo", "")
				.replace("&ugrave", "")
				.replace("&agrave", "")
				.replace("&iexcl", "")
				.replace("&aelig", "")
				.replace("&macr", "")
				.replace("&Acirc", "")
				.replace("&szlig", "")
				.replace("&Igrave", "")
				.replace("&aring", "")
				.replace("&euml", "")
				.replace("&Ucirc", "")
				.replace("&shy", "")
				.replace("&eth", "")
				.replace("&ccedil", "")
				.replace("&Ntilde", "")
				.replace("&reg", "")
				.replace("&THORN", "")
				;

		XMLDoc xmlDoc = new XMLDoc();

		try {
			xmlDoc.loadFromXMLString(result);
		} catch (Exception e) {
			e.printStackTrace();

			System.out.println("加载XML字符串失败，字符串为：" + result);
		}

		return xmlDoc;
	}

	private String doRequest(String url,String branch) {
		url = url.replace(DEFAULT_BRANCH, branch);
		
		Map<String, String> headers = new HashMap<>();
		headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
		headers.put("Accept-Encoding", "gzip, deflate, sdch");
		headers.put("Accept-Language", "zh-CN,zh;q=0.8");
		headers.put("Connection", "keep-alive");
		headers.put("Cookie",
				"__jdv=137720036|direct|-|none|-|1506419330841; __tra=122270672.15064242971051221372684.1506424297.1506424297.1506424300.1; __trv=122270672%7Cdirect%7C-%7Cnone%7C-%7C1506424297106; __tru=a421a631-668b-45a8-a293-74720d366343; mobilev=html5; mba_muid=150641933083743634130; erp1.jd.com=D491BEAAB54C4B9E76164A55DC7ED34A95A5EC9B7D94EBCAE1CFBC31C6E57DE297C11C6C9D8F4B631F138D26E6B8235815219946132A76B2F577CEF45DFCA9427B2EC255C011B8A1BD8D4001982ECCC9; sso.jd.com=083788f5020e407eac6f7bba4c769992; __jda=137720036.150641933083743634130.1506419331.1506678844.1507512592.16; __jdc=137720036; 3AB9D23F7A4B3C9B=ITNQEEJYVCMH6XITUM6TGFPDTINIS4RDU276K5RWTBFFGR2BHCHDGYGYR6MTO7C52FH6AQOOPSQWO5UJZNODJS4AXA; __jdu=150641933083743634130");
		headers.put("Host", "source.jd.com");
		headers.put("Upgrade-Insecure-Requests", "1");
		headers.put("User-Agent",
				"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36");

		String result = HttpClientUtil.executeGet(url, headers, null);

		return result;
	}

}
